package com.koron.operation.keepcontext;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.DateAndTimeUtils;
import com.koron.operation.keepcontext.bean.KeepContactBean;
import com.koron.operation.keepcontext.mapper.KeepContactMapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Api(tags = "常用联系人")
@Slf4j
@RestController
@RequestMapping("/keepcontact")
public class KeepContactController {

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    @ApiOperation(value = "新增联系人")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "business", value = "acc联系人、org单位", dataType = "String", required = true),
    })
    @PostMapping("/addUser")
    public Response addUser(@RequestBody List<KeepContactBean> acclist, @RequestParam("business") String business) {
        ADOConnection.runTask(factory -> {
            KeepContactMapper mapper = factory.getMapper(KeepContactMapper.class);
            String currAccount = getCurrUser().getAccount();
            String currName = getCurrUser().getName();

            List<KeepContactBean> existcontactlist = mapper.queryByBusinessAndMyAccount(business, currAccount);
            // 已有联系人、单位权重
            Map<String, Integer> accountWeightmap = existcontactlist.stream().collect(Collectors.toMap(KeepContactBean::getAccount, KeepContactBean::getWeight));

            // 请求人员
            List<String> reqacclist = acclist.stream().map(KeepContactBean::getAccount).collect(Collectors.toList());

            List<KeepContactBean> updatelist = existcontactlist.stream().filter(f -> reqacclist.contains(f.getAccount())).collect(Collectors.toList());
            List<KeepContactBean> insertlist = acclist.stream().filter(f -> !accountWeightmap.keySet().contains(f.getAccount())).collect(Collectors.toList());

            insertlist.stream().forEach(k -> {
                k.setBusiness(business);
                k.setId(CodeTools.getCode32());
                k.setCreateTime(new Date());
                k.setUpdateTime(new Date());
                k.setMyAccount(currAccount);
                k.setMyName(currName);
                k.setWeight(1);
            });

            updatelist.stream().forEach(k -> {
                k.setUpdateTime(new Date());
                int existweight = accountWeightmap.get(k.getAccount());
                if (existweight < 20) {
                    existweight = existweight + 1;
                }
                k.setWeight(existweight);
            });

            Lists.partition(insertlist, 300).stream().forEach(p -> {
                mapper.batchInsert(p);
            });

            Lists.partition(updatelist, 300).stream().forEach(p -> {
                mapper.updateBatchSelective(p);
            });

            return true;
        }, Boolean.class);
        return Response.ok();
    }

    @ApiOperation(value = "获取常用联系")
    @GetMapping("/getContact")
    public Response<List<KeepContactBean>> getContact(@RequestParam("business") String business) {
        List<KeepContactBean> list = ADOConnection.runTask(factory -> {
            KeepContactMapper mapper = factory.getMapper(KeepContactMapper.class);
            return mapper.queryByBusinessAndMyAccount(business, getCurrUser().getAccount());
        }, List.class);

        return Response.ok(CollUtil.sub(list, 0, 20));
    }

    @ApiOperation(value = "删除常用联系")
    @GetMapping("/removeContact")
    public Response removeContact(@RequestBody List<String> acclist, @RequestParam("business") String business) {
        ADOConnection.runTask(factory -> {
            KeepContactMapper mapper = factory.getMapper(KeepContactMapper.class);
            mapper.deleteByIdNotIn(acclist, business, getCurrUser().getAccount());
            return true;
        }, Boolean.class);
        return Response.success();
    }

    /**
     * 1、权重的衰退由时间决定，每12小时-1，下限3
     * 2、权重7天内未更新 且 权重排行小于20名 且 权重小于等于3，移除
     *
     * @return
     */
//    @ApiOperation(value = "联系人权重衰减-定时任务")
    @XxlJob(value = "declineWeight")
    @GetMapping("/declineWeight")
    public String declineWeight() {
        log.info("联系人权重衰减任务开始");
        ADOConnection.runTask(factory -> {
            KeepContactMapper mapper = factory.getMapper(KeepContactMapper.class);

            List<String> distinctMyAccount = mapper.findDistinctMyAccount();

            // 按账号前20名
            List<KeepContactBean> keepContactBeans = mapper.querytop20OnMyAccount(distinctMyAccount);
            List<String> top20list = keepContactBeans.stream().map(KeepContactBean::getMyAccount).collect(Collectors.toList());

            // 7天前的现在
            LocalDateTime beforTimeSevenTime = DateAndTimeUtils.getTimeofBeforToN(7);
            Date sevenTime = DateAndTimeUtils.ldttoDate(beforTimeSevenTime);

            mapper.deleteByUpdateTimeBeforeAndWeightBeforeAndIdIn(sevenTime, top20list);

            // 权重的衰退由时间决定，每12小时-1，下限3权重的衰退由时间决定，每12小时-1，下限10
            keepContactBeans.stream().forEach(k -> {
                if (k.getWeight() > 10) {
                    k.setWeight(k.getWeight() - 1);
                }
            });

            Lists.partition(keepContactBeans, 300).stream().forEach(p -> {
                mapper.updateBatchSelective(keepContactBeans);
            });

            return true;
        }, Boolean.class);
        log.info("联系人权重衰减任务结束");
        return null;
    }

}
